/*
  This file will hold all the function that have to do with 
  receiving the file
 */

#include "srv_net.h"

//the name of the transfered file will be a max of 512 chars
#define FN_SIZE 512
/*
 This function will start listening on the given port
 receive the file from the client
 @param port: the port to listen on
*/
void receiveFile(int port)
{
  //will hold the server socket file des.  used so it can be closed
  int srv_sockfd;
  
  //holds the client socket file descriptor
  int cli_sockfd = listenOnPort(port, &srv_sockfd);

  //will hold the file name, the file name will be a max of 512 chars
  char fileName[FN_SIZE];

 

 
  //read the file name from the client
  if(read(cli_sockfd, fileName, FN_SIZE) < 0)
    {
      perror("Error reading from client");
      exit(1);
    }
    

    close(srv_sockfd);
    close(cli_sockfd);

    printf("%s\n", fileName);
}


/*
  This function will return the file discriptor of
  the socket the server is listening on
  @param port: the port the server is listening on
  @param srv_sockfd: the file descriptor for the server socket
  this is used so the socket can be closed in the function calling this one
  @return: the socket the server is listening on
 */
int listenOnPort(int port, int *srv_sockfd)
{
  //will hold the client socket
  int cli_sockfd;

  //will hold the server address and client address infof
  struct sockaddr_in srv_addr, cli_addr;

  //try to create a server TCP socket (represented by the file descriptor)
  if((*srv_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
      //if fails, print error and exit
      perror("Socket error");
      exit(1);
    }

  //zero out the address struct before using it.  this is required
  memset((void *)&srv_addr, 0, sizeof(srv_addr));

  //signify that this address is ipv4
  srv_addr.sin_family = AF_INET;

  //listen to any ip address
  srv_addr.sin_addr.s_addr = INADDR_ANY;
  //specify what port to connect to
  srv_addr.sin_port = htons(port);
  
  //bind the socket to the server address and port
  if (bind(*srv_sockfd, (struct sockaddr *) &srv_addr, sizeof(srv_addr)) < 0)
    { 
      perror("Error on binding");
      exit(1);
    }
  //listen on the server socket and allow max number 
  //of connections on backlog queue
  listen(*srv_sockfd, SOMAXCONN);

  //stor the client length for the accept function
  socklen_t clilen = sizeof(cli_addr);

  printf("Waiting for connection...\n");

  //accept incoming connections.  will block until connection is received
  if((cli_sockfd = accept(*srv_sockfd, 
                 (struct sockaddr *) &cli_addr, &clilen)) < 0)
    {
      //if fails, print error and exit
      perror("Error on accepting incoming connections");
      exit(1);
    }

  return cli_sockfd;
}
